//! 向量(Vector)示例
//!
//! `Vec<T>` 是 Rust 中最常用的集合类型之一，它允许我们在单个数据结构中存储多个值。
//!
//! ## 知识点总结
//!
//! | 知识点 | 说明 |
//! |--------|------|
//! | 创建向量 | 使用`Vec::new()`或`vec![]`宏创建 |
//! | 更新向量 | 使用`push`方法添加元素 |
//! | 读取元素 | 通过索引或`get`方法访问元素 |
//! | 迭代向量 | 使用`for`循环或迭代器方法 |
//! | 存储不同类型的值 | 使用枚举或trait对象存储不同类型 |

/// 创建向量的基础方法
pub fn creating_vectors() {
    // 使用 Vec::new() 创建空向量
    let v: Vec<i32> = Vec::new();

    // 使用 vec! 宏创建包含初始值的向量
    let v = vec![1, 2, 3];

    // 创建指定类型和大小的向量
    let v = Vec::<i32>::with_capacity(5);

    println!("向量创建示例:");
    println!("空向量: {:?}", v);
    println!("初始值向量: {:?}", v);
    println!("预分配容量向量容量: {}", v.capacity());

    // 可变的方式定义 vector
    let mut v = Vec::new();
    // 更新
    v.push(3);
    println!("可变向量: {:?}", v);

    // 使用 get 方法以索引作为参数来返回一个 Option<&T>。
    let v1 = vec![1, 2, 3, 4, 5];
    let v3 = &v1[2];
    match v1.get(2) {
        Some(v3) => println!("获取到vec中的值{}", v3),
        None => println!("获取值失败"),
    }
    println!("向量 v1: {:?}", v1);
}

/// 更新向量
pub fn updating_vectors() {
    // 创建可变向量
    let mut v = Vec::new();

    // 使用 push 添加元素
    v.push(5);
    v.push(6);
    v.push(7);

    println!("更新向量示例:");
    println!("添加元素后: {:?}", v);

    // 使用宏创建向量并修改
    let mut v = vec![1, 2, 3];
    v.push(4);
    println!("宏创建并添加元素: {:?}", v);
}

/// 读取向量元素
pub fn reading_vectors() {
    let v = vec![1, 2, 3, 4, 5];

    // 通过索引访问元素（索引从0开始）
    let third: &i32 = &v[2];
    println!("第三个元素（索引访问）: {}", third);

    // 使用 get 方法安全访问元素
    match v.get(2) {
        Some(third) => println!("第三个元素（get方法）: {}", third),
        None => println!("没有第三个元素"),
    }

    // 访问不存在的元素
    match v.get(10) {
        Some(value) => println!("第11个元素: {}", value),
        None => println!("没有第11个元素，索引超出范围"),
    }

    // 索引访问vector的元素
    let v2 = vec![1, 2, 3];
    let element = &v2[0];
    println!("索引访问vector元素: {}", element);
}

/// 遍历向量
pub fn iterating_vectors() {
    let v = vec![10, 20, 30, 40, 50];

    // 不可变遍历
    println!("不可变遍历:");
    for i in &v {
        println!("元素: {}", i);
    }

    // 可变遍历并修改元素
    let mut v = vec![1, 2, 3, 4, 5];
    println!("修改前: {:?}", v);

    for i in &mut v {
        *i *= 2; // 将每个元素乘以2
    }

    println!("修改后: {:?}", v);

    // 遍历vector
    println!("遍历vector:");
    let v = vec![1, 2, 3, 4, 5];
    for i in &v {
        println!("{i}");
    }

    // 使用foreach方式遍历
    println!("使用foreach方式遍历:");
    v.iter().for_each(|x| println!("{x}"));
}

/// 存储不同类型的值
///
/// 使用枚举可以在向量中存储不同类型的值
#[allow(dead_code)]
enum SpreadsheetCell {
    Int(i32),
    Float(f64),
    Text(String),
}

pub fn mixed_types() {
    let row = vec![SpreadsheetCell::Int(3), SpreadsheetCell::Text(String::from("blue")), SpreadsheetCell::Float(10.12)];

    println!("混合类型向量:");
    for cell in &row {
        match cell {
            SpreadsheetCell::Int(value) => println!("整数: {value}"),
            SpreadsheetCell::Float(value) => println!("浮点数: {value}"),
            SpreadsheetCell::Text(value) => println!("文本: {value}"),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_creating_vectors() {
        creating_vectors();
    }

    #[test]
    fn test_updating_vectors() {
        updating_vectors();
    }

    #[test]
    fn test_reading_vectors() {
        reading_vectors();
    }

    #[test]
    fn test_iterating_vectors() {
        iterating_vectors();
    }

    #[test]
    fn test_mixed_types() {
        mixed_types();
    }
}
